/**
	Copyright (c) 2010 ATTi 
	All rights reserved.
	Author: Michael Shu
	Date: 1/22/2010
*/

trigger EmailToNewCase on EmailMessage (before insert, before update) {
	String ExcpeitonEmaiList = 'mailer-daemon@salesforce.com;';
	set<String> RecordTypeNames = GeneralConstants.RT_CCIR;
                                     
	String REG_CORE   = 'ref\\s*:\\s*[0-9A-Za-z]{1,15}\\s*\\.\\s*500[0-9A-Za-z]{1,12}\\s*:\\s*ref';
	String REG_EXTEND = '\\[\\s*' + REG_CORE + '\\s*\\]';
    Pattern refPattern_core   = Pattern.compile(REG_CORE);
	Pattern refPattern_extend = Pattern.compile(REG_EXTEND);
        	   	
	List<EmailMessage> messages = new List<EmailMessage>();
	Map<ID, EmailMessage> casesWithMessages = new Map<ID, EmailMessage>();
	
	for(EmailMessage e : trigger.new){
		Boolean isFromAddressValid = e.FromAddress == null || (e.FromAddress != null && !ExcpeitonEmaiList.toUpperCase().contains(e.FromAddress.toUpperCase()));
		Boolean match = (e.Subject != null && refPattern_extend.matcher(e.Subject).find()) || (e.textBody != null && refPattern_core.matcher(e.textBody).find());
		if(e.Incoming && isFromAddressValid && match){
			messages.add(e);
			casesWithMessages.put(e.ParentId, e);
		}
	}
	
	if(!messages.isEmpty()){
		Map<Id, Case> closedCases = new Map<Id, Case>([select Id from Case where IsClosed = true and Id IN : casesWithMessages.keySet() and RecordType.Name IN : RecordTypeNames]);
		if(!closedCases.isEmpty()){
			Database.DMLOptions dmo = new Database.DMLOptions();
    		dmo.assignmentRuleHeader.useDefaultRule= true;
    		dmo.EmailHeader.triggerAutoResponseEmail = false;
    		
			List<Case> queriedOldClosedCases = (List<Case>) CustomCloneFunctionClass.queryObjs('Case', closedCases.keySet());
			Map<Id, Case> newCases = new Map<ID, Case>();
			Set<ID> CCIRIds = GeneralConstants.getRecordTypeIdsByNames('Case', GeneralConstants.RT_CCIR);
			ID incidentRTId = RecordTypeHelper.GetRecordTypeId('Case', 'IOG Incident');
			for(Case old : queriedOldClosedCases){
				Case n = (Case) old.clone(false, true); // clear Id, deep clone
				n.Status = 'Open';
				n.Origin = 'Email';
				EmailMessage msg = casesWithMessages.get(old.Id);
				if(msg != null){
					n.Subject = msg.Subject;
					n.Description = msg.TextBody;
					n.SuppliedEmail = GeneralConstants.checkAndTransformWebEmail(msg.FromAddress);
					n.SuppliedName = msg.FromName;
				}
				if(CCIRIds.contains(old.RecordTypeId)){ // for IOG only
					n.IR_Priority__c = 'Standard';
					n.CRF_PACKAGE__c = null;
					n.CSS_CRF_RequestType__c = null;
					n.Fulfillment_Item__c = null;
					n.RPI__c = null;
					n.Item_ID__c = null;
					n.ParentId = null;
					n.AFrontier_Issue__c = null;
					n.AFrontier_Reason__c = null;
					n.CSS_ProductFamily__c = null;
					n.RecordTypeId = incidentRTId;
					dmo.assignmentRuleHeader.useDefaultRule= false;
					//AD-30505
					//if(old.Last_Queue_Owner__c != null){ 
					//	n.OwnerId = old.Last_Queue_Owner__c;
					//}else{
					String qOwnerName;
					if(old.IR_Priority__c == CaseIOGClass.STANDARD){
						qOwnerName = CaseIOGClass.getIOGCustomerSupportQueueOwnersByRegions(old);
					}else{
						qOwnerName = CaseIOGClass.getIOGEscalateQueueOwnersByRegions(old);					
					}
					CaseIOGClass.setOwnerIdAndLastQueueOwner(n, qOwnerName);
					//}
				}
				n.setOptions(dmo);
				newCases.put(old.Id, n);
			}
			Boolean isPass = true;
			if(!newCases.isEmpty()){
				try{
					insert newCases.values();
				}catch(Exception ex){
					isPass = false;
					GeneralConstants.mailAnyExceptionToMe('EmailToNewCase','EmailToNewCase Fail : couldn\'t insert new cases, emails will stay with the old case without changes', ex);
				}
			}
			if(isPass){
				for(EmailMessage e : messages){
					if(closedCases.containsKey(e.ParentId)){ // email message associate with a closed case
						e.Subject = (e.Subject == null)? null : e.Subject.replaceAll(REG_EXTEND, '');
						e.textBody = (e.textBody == null)? null : e.textBody.replaceAll( REG_EXTEND, '');
						e.htmlBody = (e.htmlBody == null)? null : e.htmlBody.replaceAll( REG_EXTEND, '');	
						e.textBody = (e.textBody == null)? null : e.textBody.replaceAll( REG_CORE, '');
						e.htmlBody = (e.htmlBody == null)? null : e.htmlBody.replaceAll( REG_CORE, '');	
						Case newcs = newCases.get(e.ParentId);
						if(newcs != null){
							e.ParentId = newcs.Id;
						}
					}
				}
			}
		}	
	}
}